package com.wearemanner.triangle.framework.mock;

import com.github.jsonzou.jmockdata.DataConfig;
import com.github.jsonzou.jmockdata.MockConfig;
import com.wearemanner.triangle.common.util.Dates;
import lombok.Getter;

import java.lang.ref.WeakReference;
import java.util.Date;

/**
 * 全局MockData配置
 *
 * @author Sunny
 * @date 2021/2/18
 */
@Getter
public final class MockConfigTemplate {

    private MockConfigTemplate(MockConfig mockConfig) {
        this.mockConfig = mockConfig;
    }

    /** 全局Mock配置 */
    private final MockConfig mockConfig;

    public static Builder builder() {
        return new Builder();
    }

    public static MockConfigTemplate defaultConfig() {
        return MockConfigTemplate.builder().build();
    }

    public static class Builder {

        private Builder() {}

        private static final MockConfig MOCK_CONFIG = MockConfig.newInstance()
                //支持循环依赖、自循环
                .setEnabledCircle(true)
                //排除id字段
                .excludes("id");

        static {
            //注册模拟器，弱引用对象不赋值,JMockData暂不支持弱引用
            MOCK_CONFIG.registerMocker(mockConfig -> null, WeakReference.class);
        }

        private DataConfigBuilder builder(DataConfig dataConfig) {
            return new DataConfigBuilder(this, dataConfig);
        }

        /**
         * 需要配置规则的字段
         *
         * @param fieldNames 字段集合
         * @author Sunny
         * @date 2021/2/19
         */
        public DataConfigBuilder config(String ... fieldNames) {
            return builder(MOCK_CONFIG.subConfig(fieldNames));
        }

        public MockConfigTemplate build() {
            return new MockConfigTemplate(MOCK_CONFIG);
        }

    }

    /**
     * 字段规则配置器
     */
    public static class DataConfigBuilder {

        private DataConfigBuilder(Builder builder, DataConfig dataConfig) {
            this.builder = builder;
            this.dataConfig = dataConfig;
        }

        private final Builder builder;

        /** 字段规则配置 */
        private final DataConfig dataConfig;

        public DataConfig getDataConfig() {
            return dataConfig;
        }

        /**
         * 需要配置规则的字段
         *
         * @param fieldNames 字段集合
         * @author Sunny
         * @date 2021/2/19
         */
        public DataConfigBuilder config(String ... fieldNames) {
            return builder.config(fieldNames);
        }

        /**
         * 生成int值的范围
         *
         * @param min 最小值
         * @param max 最大值
         * @author Sunny
         * @date 2021/2/19
         */
        public DataConfigBuilder intRange(int min, int max) {
            dataConfig.intRange(min, max);
            return this;
        }

        /**
         * 生成long值的范围
         *
         * @param min 最小值
         * @param max 最大值
         * @author Sunny
         * @date 2021/2/19
         */
        public DataConfigBuilder longRange(long min, long max) {
            dataConfig.longRange(min, max);
            return this;
        }

        /**
         * 根据正则表达式规则生成数据
         *
         * @param stringRegex 正则表达式
         * @author Sunny
         * @date 2021/2/19
         */
        public DataConfigBuilder stringRegex(String stringRegex) {
            dataConfig.stringRegex(stringRegex);
            return this;
        }

        /**
         * 生成字符串的长度
         *
         * @param min 最小值
         * @param max 最大值
         * @author Sunny
         * @date 2021/2/19
         */
        public DataConfigBuilder sizeRange(int min, int max) {
            dataConfig.sizeRange(min, max);
            return this;
        }

        /**
         * 生成日期的范围
         *
         * @param min 最小值
         * @param max 最大值
         * @author Sunny
         * @date 2021/2/19
         */
        public DataConfigBuilder dateRange(Date min, Date max) {
            dataConfig.dateRange(Dates.formatDateTime(min), Dates.formatDateTime(max));
            return this;
        }

        /**
         * 生成过去的随机日期的范围
         *
         * @author Sunny
         * @date 2021/2/19
         */
        public DataConfigBuilder pastDateRange() {
            dataConfig.dateRange(Mocks.pastStr(), Dates.getDateTimeStr());
            return this;
        }

        /**
         * 生成未来的随机日期的范围
         *
         * @author Sunny
         * @date 2021/2/19
         */
        public DataConfigBuilder futureDateRange() {
            dataConfig.dateRange(Mocks.futureStr(), Dates.getDateTimeStr());
            return this;
        }

        public MockConfigTemplate build() {
            return builder.build();
        }

    }

}
